﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using HslCommunication.Core;
using HslCommunication.Core.Net;
using HslCommunication.LogNet;
using HslCommunication.Reflection;

namespace HslCommunication.Enthernet
{
	/// <summary>
	/// 一个终极文件管理服务器，可以实现对所有的文件分类管理，本服务器支持读写分离，支持同名文件，
	/// 客户端使用<see cref="T:HslCommunication.Enthernet.IntegrationFileClient" />进行访问，支持上传，下载，删除，请求文件列表，校验文件是否存在操作。<br />
	/// An ultimate file management server, which can realize classified management of all files. This server supports read-write separation, 
	/// supports files with the same name, and the client uses <see cref="T:HslCommunication.Enthernet.IntegrationFileClient" /> to access, 
	/// supports upload, download, delete, and request files List, check whether the file exists operation.
	/// </summary>
	/// <remarks>
	/// 本文件的服务器支持存储文件携带上传人的信息，备注信息，文件名被映射成了新的名称，无法在服务器直接查看文件信息。
	/// </remarks>
	/// <example>
	/// 以下的示例来自Demo项目，创建了一个简单的服务器对象。
	/// <code lang="cs" source="TestProject\FileNetServer\FormFileServer.cs" region="Ultimate Server" title="UltimateFileServer示例" />
	/// </example>
	// Token: 0x020000F7 RID: 247
	public class UltimateFileServer : NetworkFileServerBase
	{
		/// <summary>
		/// 获取当前的针对文件夹的文件管理容器的数量<br />
		/// Get the current number of file management containers for the folder
		/// </summary>
		// Token: 0x060014E6 RID: 5350 RVA: 0x0006C4A7 File Offset: 0x0006A6A7
		[HslMqttApi(Description = "Get the current number of file management containers for the folder")]
		public int GroupFileContainerCount()
		{
			return this.m_dictionary_group_marks.Count;
		}

		/// <summary>
		/// 获取当前目录的文件列表管理容器，如果没有会自动创建，通过该容器可以实现对当前目录的文件进行访问<br />
		/// Get the file list management container of the current directory. If not, it will be created automatically. 
		/// Through this container, you can access files in the current directory.
		/// </summary>
		/// <param name="filePath">路径信息</param>
		/// <returns>文件管理容器信息</returns>
		// Token: 0x060014E7 RID: 5351 RVA: 0x0006C4B4 File Offset: 0x0006A6B4
		public GroupFileContainer GetGroupFromFilePath(string filePath)
		{
			filePath = filePath.ToUpper();
			this.hybirdLock.Enter();
			bool flag = this.m_dictionary_group_marks.ContainsKey(filePath);
			GroupFileContainer groupFileContainer;
			if (flag)
			{
				groupFileContainer = this.m_dictionary_group_marks[filePath];
			}
			else
			{
				groupFileContainer = new GroupFileContainer(base.LogNet, filePath);
				this.m_dictionary_group_marks.Add(filePath, groupFileContainer);
			}
			this.hybirdLock.Leave();
			return groupFileContainer;
		}

		/// <summary>
		/// 从套接字接收文件并保存，更新文件列表
		/// </summary>
		/// <param name="socket">套接字</param>
		/// <param name="savename">保存的文件名</param>
		/// <returns>是否成功的结果对象</returns>
		// Token: 0x060014E8 RID: 5352 RVA: 0x0006C528 File Offset: 0x0006A728
		private OperateResult<FileBaseInfo> ReceiveFileFromSocketAndUpdateGroup(Socket socket, string savename)
		{
			FileInfo fileInfo = new FileInfo(savename);
			string text = base.CreateRandomFileName();
			string text2 = Path.Combine(fileInfo.DirectoryName, text);
			OperateResult<FileBaseInfo> operateResult = base.ReceiveFileFromSocket(socket, text2, null);
			bool flag = !operateResult.IsSuccess;
			OperateResult<FileBaseInfo> result;
			if (flag)
			{
				base.DeleteFileByName(text2);
				result = operateResult;
			}
			else
			{
				GroupFileContainer groupFromFilePath = this.GetGroupFromFilePath(fileInfo.DirectoryName);
				string fileName = groupFromFilePath.UpdateFileMappingName(fileInfo.Name, operateResult.Content.Size, text, operateResult.Content.Upload, operateResult.Content.Tag);
				this.DeleteExsistingFile(fileInfo.DirectoryName, fileName);
				OperateResult operateResult2 = base.SendStringAndCheckReceive(socket, 1, StringResources.Language.SuccessText);
				bool flag2 = !operateResult2.IsSuccess;
				if (flag2)
				{
					result = OperateResult.CreateFailedResult<FileBaseInfo>(operateResult2);
				}
				else
				{
					result = OperateResult.CreateSuccessResult<FileBaseInfo>(operateResult.Content);
				}
			}
			return result;
		}

		/// <summary>
		/// 从套接字接收文件并保存，更新文件列表
		/// </summary>
		/// <param name="socket">套接字</param>
		/// <param name="savename">保存的文件名</param>
		/// <returns>是否成功的结果对象</returns>
		// Token: 0x060014E9 RID: 5353 RVA: 0x0006C60C File Offset: 0x0006A80C
		[DebuggerStepThrough]
		private Task<OperateResult<FileBaseInfo>> ReceiveFileFromSocketAndUpdateGroupAsync(Socket socket, string savename)
		{
			UltimateFileServer.<ReceiveFileFromSocketAndUpdateGroupAsync>d__6 <ReceiveFileFromSocketAndUpdateGroupAsync>d__ = new UltimateFileServer.<ReceiveFileFromSocketAndUpdateGroupAsync>d__6();
			<ReceiveFileFromSocketAndUpdateGroupAsync>d__.<>t__builder = AsyncTaskMethodBuilder<OperateResult<FileBaseInfo>>.Create();
			<ReceiveFileFromSocketAndUpdateGroupAsync>d__.<>4__this = this;
			<ReceiveFileFromSocketAndUpdateGroupAsync>d__.socket = socket;
			<ReceiveFileFromSocketAndUpdateGroupAsync>d__.savename = savename;
			<ReceiveFileFromSocketAndUpdateGroupAsync>d__.<>1__state = -1;
			<ReceiveFileFromSocketAndUpdateGroupAsync>d__.<>t__builder.Start<UltimateFileServer.<ReceiveFileFromSocketAndUpdateGroupAsync>d__6>(ref <ReceiveFileFromSocketAndUpdateGroupAsync>d__);
			return <ReceiveFileFromSocketAndUpdateGroupAsync>d__.<>t__builder.Task;
		}

		/// <summary>
		/// 根据文件的显示名称转化为真实存储的名称，例如 123.txt 获取到在文件服务器里映射的文件名称，例如返回 b35a11ec533147ca80c7f7d1713f015b7909
		/// </summary>
		/// <param name="factory">第一大类</param>
		/// <param name="group">第二大类</param>
		/// <param name="id">第三大类</param>
		/// <param name="fileName">文件显示名称</param>
		/// <returns>是否成功的结果对象</returns>
		// Token: 0x060014EA RID: 5354 RVA: 0x0006C660 File Offset: 0x0006A860
		private string TransformFactFileName(string factory, string group, string id, string fileName)
		{
			string filePath = base.ReturnAbsoluteFilePath(factory, group, id);
			GroupFileContainer groupFromFilePath = this.GetGroupFromFilePath(filePath);
			return groupFromFilePath.GetCurrentFileMappingName(fileName);
		}

		/// <summary>
		/// 删除已经存在的文件信息，文件的名称需要是guid名称，例如 b35a11ec533147ca80c7f7d1713f015b7909
		/// </summary>
		/// <param name="path">文件的路径</param>
		/// <param name="fileName">文件的guid名称，例如 b35a11ec533147ca80c7f7d1713f015b7909</param>
		// Token: 0x060014EB RID: 5355 RVA: 0x0006C68C File Offset: 0x0006A88C
		private void DeleteExsistingFile(string path, string fileName)
		{
			this.DeleteExsistingFile(path, new List<string>
			{
				fileName
			});
		}

		/// <summary>
		/// 删除已经存在的文件信息，文件的名称需要是guid名称，例如 b35a11ec533147ca80c7f7d1713f015b7909
		/// </summary>
		/// <param name="path">文件的路径</param>
		/// <param name="fileNames">文件的guid名称，例如 b35a11ec533147ca80c7f7d1713f015b7909</param>
		// Token: 0x060014EC RID: 5356 RVA: 0x0006C6A4 File Offset: 0x0006A8A4
		private void DeleteExsistingFile(string path, List<string> fileNames)
		{
			foreach (string text in fileNames)
			{
				bool flag = !string.IsNullOrEmpty(text);
				if (flag)
				{
					string fileUltimatePath = Path.Combine(path, text);
					FileMarkId fileMarksFromDictionaryWithFileName = base.GetFileMarksFromDictionaryWithFileName(text);
					fileMarksFromDictionaryWithFileName.AddOperation(delegate
					{
						bool flag2 = !this.DeleteFileByName(fileUltimatePath);
						if (flag2)
						{
							ILogNet logNet = this.LogNet;
							if (logNet != null)
							{
								logNet.WriteInfo(this.ToString(), StringResources.Language.FileDeleteFailed + fileUltimatePath);
							}
						}
						else
						{
							ILogNet logNet2 = this.LogNet;
							if (logNet2 != null)
							{
								logNet2.WriteInfo(this.ToString(), StringResources.Language.FileDeleteSuccess + fileUltimatePath);
							}
						}
					});
				}
			}
		}

		/// <inheritdoc />
		// Token: 0x060014ED RID: 5357 RVA: 0x0006C738 File Offset: 0x0006A938
		[DebuggerStepThrough]
		protected override void ThreadPoolLogin(Socket socket, IPEndPoint endPoint)
		{
			UltimateFileServer.<ThreadPoolLogin>d__10 <ThreadPoolLogin>d__ = new UltimateFileServer.<ThreadPoolLogin>d__10();
			<ThreadPoolLogin>d__.<>t__builder = AsyncVoidMethodBuilder.Create();
			<ThreadPoolLogin>d__.<>4__this = this;
			<ThreadPoolLogin>d__.socket = socket;
			<ThreadPoolLogin>d__.endPoint = endPoint;
			<ThreadPoolLogin>d__.<>1__state = -1;
			<ThreadPoolLogin>d__.<>t__builder.Start<UltimateFileServer.<ThreadPoolLogin>d__10>(ref <ThreadPoolLogin>d__);
		}

		/// <inheritdoc />
		// Token: 0x060014EE RID: 5358 RVA: 0x0006C77F File Offset: 0x0006A97F
		public override string ToString()
		{
			return string.Format("UltimateFileServer[{0}]", base.Port);
		}

		/// <summary>
		/// 所有文件组操作的词典锁
		/// </summary>
		// Token: 0x040004F2 RID: 1266
		internal Dictionary<string, GroupFileContainer> m_dictionary_group_marks = new Dictionary<string, GroupFileContainer>();

		/// <summary>
		/// 词典的锁
		/// </summary>
		// Token: 0x040004F3 RID: 1267
		private SimpleHybirdLock hybirdLock = new SimpleHybirdLock();
	}
}
